/**
 * @author 刘超
 * @Note 该插件主要是用来实现一个浮动的选择层
 * @usePage [通知规则下的接受规则添加和修改]
 * @ps 该插件由纯JS代码组成,且无任何依赖关系,可单独使用.亦可辅助其他插件使用.
 * @PS 为了良好的扩展性,每个功能都对应一个方法,在调用时通过判断来调用.以增加各种可能性
 * @PS 改良了动态div和span的生成方法.代码更简洁,样式更容易控制
 */
(function (){
	/**
	 * FloatChooseLayer 类的全局变量
	 * @Note 大部分的值是固定的.但是少部分的值会发生改变,例如div id 的编号就是递增的
	 */
	FCL_StaticProperty = {
			divIdNumber : 1, // div id 的编号 防止div id 重复
			universalTimeInterval : 50,
			autoCDInterval : 200, // 自动监控是否要关闭层的时间间隔
			findTTargetsTimes : 5 // 寻找目标5次,如果找不到就放弃
	};
	FCL_StaticProperty.getDivIdNumber = function (){
		return this.divIdNumber++;
	};


	FloatChooseLayer = function (params){
		this.options = [];//						支持参数赋值
		this.tTargets = []; // Triggering Target : 触发目标者[复数] 传入ID 最后生成目标对象,支持参数赋值
		this.tTargetMark = false; // 标记目标是否获得了焦点或者是鼠标悬停在其表面
		this.divStyle = {}; // 格式 {widht:"100px",margin:"12px",...}			支持参数赋值
		this.div = {};
		this.isPointerOver = {yes:"Hover",no:""}; // 请勿重新赋值 但是可以新增加值
		this.spanStyle = {}; // 同 divStyle						支持参数赋值
		this.spanBG = {hover:"#ccc",out:"white"}; // 修背景颜色时请将此也修改		支持参数赋值
		this.CustomMethods = { // 自定义方法										支持参数赋值
				spanClickBefore : null, // span click 执行之前的动作
				spanClickAfter : null   // span click 执行操作之后的动作
		}

		this.initParams(params);
		this.createDiv(this.divStyle);
		this.ttBindEventResult = this.ttBindEvent();

	};
	FloatChooseLayer.prototype.$ = function (id){
		return document.getElementById(id);
	};
	FloatChooseLayer.prototype.initParams = function (params){
		if(!params){ return false; }
		for(var key in params){
			this[key] = params[key];
		}
	};
	/**
	 * ttBindEvent : Triggering Target Bind Event
	 */
	FloatChooseLayer.prototype.ttBindEvent = function (){
		var this_ = this;
		if(!this_.tTargets){return false;}

		var tts = this_.tTargets;
		this_.tTargets = new Object(); // 重新赋值 且改变类型
		var findTimes = 0;

		function start(){
			if(this_.$(tts[0])){
				for(var i=0; i<tts.length; i++){
					this_.tTargets[tts[i]] = this_.$(tts[i]);
				}

				bindEvent();

				return true;
			}else{
				if(findTimes >= FCL_StaticProperty.findTTargetsTimes){ return false; }
				findTimes ++;

				setTimeout(start,FCL_StaticProperty.universalTimeInterval);
			}
		}
		//获取元素的Y标
		function getTop(e){
			var offset=e.offsetTop;
			if(e.offsetParent!=null){
				offset+=getTop(e.offsetParent);
			}
			return offset;
		}
		//获取元素的X标
		function getLeft(e){
			var offset=e.offsetLeft;
			if(e.offsetParent!=null){
				offset+=getLeft(e.offsetParent);
			}
			return offset;
		}
		function bindEvent(){
			var doms = this_.tTargets;
			for(var key in doms){
				var dom = doms[key];
				var domTag = dom.type ? dom.type : dom.tagName.toLowerCase();
				if(dom.type == "text"){
					ttTagTextBox(dom);
				}
			}
		}
		function ttTagTextBox(dom){ // 文本框
			dom.onkeydown = function (){ // 只允许用户按切换键[Tab]
				if(event.keyCode != 9){
					return event.returnValue=false;
				}
			};

			dom.onfocus = function (){
				this_.tTargetMark = true;

				this_.div.style.top = getTop(this) + this.offsetHeight;
				this_.div.style.left = getLeft(this);

				var span = dynamicallyGeneratedDiv(this);

				this_.div.style.display = "";
				this_.autoColosedDiv();

				spanPosition(span);
			};

			dom.onblur = function (){
				this_.tTargetMark = false;
			};
		}

		function dynamicallyGeneratedDiv(dom){
			this_.div.innerHTML = "";

			var os = this_.options;
			var spanPosition = null;
			for(var i=0; i<os.length; i++){
				var span = generateSpan({html:os[i]});
				if(dom.value == os[i]){
					span.style.background = this_.spanBG.hover;
					spanPosition = span;
				}else{
					span.onmouseout = function (){
						this.style.background = this_.spanBG.out;
					};
					span.onmouseover = function (){
						this.style.background = this_.spanBG.hover;
					};
				}

				span.onclick = function (){
					if(this_.CustomMethods.spanClickBefore){
						this_.CustomMethods.spanClickBefore();
					}

					dom.value = this.innerHTML;
					this_.div.style.display = "none";

					if(this_.CustomMethods.spanClickAfter){
						this_.CustomMethods.spanClickAfter();
					}
				}

				this_.div.appendChild(span);
			}

			return spanPosition;
		}
		function generateSpan(params){ // 创建一个span
			if(!params){return false;}
			var ssObj = {   // span style
					width : "35",
					background : "white",
					border : "2px solid gray",
					margin : "1px 2px 1px 2px",
					cursor : "pointer",
					textAlign : "center",
					overflow : "auto"
			};

			if(this_.spanStyle){ // 用户自定义span样式
				for(var key in this_.spanStyle){
					ssObj[key] = this_.spanStyle[key];
				}
			}

			var span = document.createElement("span");

			var ss = span.style;
			for(var key in ssObj){ // 设置样式
				ss[key] = ssObj[key];
			}

			span.innerHTML = params.html;
			return span;
		}
		function spanPosition(s){ // 显示用户上次所选的值所在的位置
			function start(){ // 加上自身高度视为了防止该span被掩藏一半甚至更多
				if((s.offsetTop+s.offsetHeight) > this_.div.offsetHeight){
					this_.div.scrollTop = s.offsetTop;
				}else{
					this_.div.scrollTop = 0;
				}
			}
			setTimeout(start,100);
		}

		start();
	}
	/**
	 * 创建一个div
	 * ds : div style 的缩写
	 */
	FloatChooseLayer.prototype.createDiv = function (params){
		var this_ = this;
		var dsObj = { // div 的基本样式
				width : "150",
				height : "65",
				background : "white",
				border : "1px solid blue",
				position : "absolute",
				overflow : "auto",
				zIndex : 100,
				display : "none"
		};

		if(params){ //  用户自定义样式
			for(var key in params){
				dsObj[key] = params[key];
			}
		}

		function start(){
			if(document.body){
				var div = document.createElement("div");
				div.id = "fcl"+FCL_StaticProperty.getDivIdNumber()+"Div";
				div.isPointerOver = this_.isPointerOver.yes; // 鼠标是否悬停在该div上面

				var ds = div.style;
				for(var key in dsObj){ // 设置样式
					ds[key] = dsObj[key];
				}

				document.body.appendChild(div);

				div.onmouseout = function (){
					this.isPointerOver = this_.isPointerOver.no;
				};
				div.onmouseover = function (){
					this.isPointerOver = this_.isPointerOver.yes;
				};

				this_.div = div;
			}else{
				setTimeout(start, this_.findInterval);
			}
		}
		start();
	};
	FloatChooseLayer.prototype.autoColosedDiv = function (){
		var this_ = this;
		var div = this_.div;
		function start(){

			if(div){ // 减少客户端负担的判断
				var ds = div.style;
				if(!ds.display){
					var isPointerOver = div.isPointerOver == this_.isPointerOver.no;
					if(isPointerOver && !this_.tTargetMark){
						ds.display = "none";
					}else{
						setTimeout(start,FCL_StaticProperty.autoCDInterval);
					}
				}
			}

		}
		start();
	};

	Object.prototype.toString = function (){ // 重写Json的toString 方法 [测试用的,本插件中并未使用]
		var s = "{";
		if(this){
			for(var atrr in this){
				s += atrr + ":";
				s += this[atrr];
				s += ",";
			};
		}
		var len = s.lastIndexOf(",");
		if(len > -1){
	        s = s.substring(0,len);
		}
		s += "}";

		return s;
	};
})();